//
//  RocBluetoothManager.m
//  RocRemoteControlProject
//
//  Created by 新致李照鹏 on 2018/12/19.
//  Copyright © 2018年 Roc. All rights reserved.
//

#import "RocBluetoothManager.h"
#import <CoreBluetooth/CoreBluetooth.h>

//API_AVAILABLE(ios(10.0))
@interface RocBluetoothManager () <CBCentralManagerDelegate, CBPeripheralDelegate>

/** 中心管理者 */
@property (nonatomic, strong) CBCentralManager *centralManager;
/** 扫描到的外设 */
@property (nonatomic, strong) NSMutableArray *peripherals;
/** 需要连接的外设 */
@property (nonatomic, strong) CBPeripheral *peripheral;

// block块回调
@property (nonatomic, copy) bluetoothStatusCallBack blueStatusCallBack;
@property (nonatomic, copy) bluetoothScanCallBack blueScanCallBack;

@end

@implementation RocBluetoothManager

#pragma mark - 暴露的类方法
/**
 * 开始监控蓝牙状态
 */
- (void)startMonitorBluetoothStatus:(bluetoothStatusCallBack)callBack
{
    self.blueStatusCallBack = callBack;
    [self centralManager];
}

/**
开始扫描设备
*/
- (void)startScanDevice:(bluetoothScanCallBack)callBack
{
    self.blueScanCallBack = callBack;
    [self blueToDo_StartScan];
}

#pragma mark - 蓝牙逻辑方法
/**
 开始扫描设备
 */
- (void)blueToDo_StartScan
{
    self.is_Scaning = YES;
    if (![self.centralManager isScanning]) {
        [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    }
    
}

- (void)blueToDo_connectPeripheral
{
    if (self.peripheral) {
        [self.centralManager connectPeripheral:self.peripheral options:nil];
    }
}


/**
 
 */
- (void)blueToDo_StopScanEndConnect
{
    //停止扫描
    if([self.centralManager isScanning]){
        [self.centralManager stopScan];
    }
    //断开连接
    if(self.centralManager != nil && self.peripheral.state == CBPeripheralStateConnected){
        [self.centralManager cancelPeripheralConnection:self.peripheral];
    }
}
#pragma mark - 蓝牙初始化
// 中心管理者(管理设备的扫描和连接)
- (CBCentralManager *)centralManager
{
    if (!_centralManager)
    {
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    return _centralManager;
}
// 存储的设备
- (NSMutableArray *)peripherals
{
    if (!_peripherals) {
        _peripherals = [NSMutableArray array];
    }
    return _peripherals;
}
#pragma mark - CBPeripheralDelegate 外部设备
/**
 扫描到服务
 
 @param peripheral 服务对应的设备
 @param error 扫描错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // 是否获取失败
    if (error) {
        NSLog(@"获取服务失败==%@", peripheral.name);
        return;
    }
    for (CBService *service in peripheral.services) {
        NSLog(@"设备的服务==%@,UUID==%@,count==%lu",service,service.UUID,peripheral.services.count);
        // 外设发现特征
        [peripheral discoverCharacteristics:nil forService:service];
    }
}

/**
 扫描到对应的特征
 
 @param peripheral 设备
 @param service 特征对应的服务
 @param error 错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // 遍历所有的特征
    for (CBCharacteristic *characteristic in service.characteristics)
    {
        //该特征值具有读写权限
        if(characteristic.properties & CBCharacteristicPropertyWrite && characteristic.properties & CBCharacteristicPropertyRead){
            
        }
        NSLog(@"设备的服务==%@,服务对应的特征值==%@,UUID==%@,count==%lu",service,characteristic,characteristic.UUID,service.characteristics.count);
        //11、获取特征对应的描述 会回调didUpdateValueForDescriptor
        [peripheral discoverDescriptorsForCharacteristic:characteristic];
        //12、获取特征的值 会回调didUpdateValueForCharacteristic
        [peripheral readValueForCharacteristic:characteristic];
        
    }
}

/**
 根据特征读到数据
 
 @param peripheral 读取到数据对应的设备
 @param characteristic 特征
 @param error 错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
    NSData *data = characteristic.value;
    NSLog(@"根据特征读到数据 : %@",data);
    //    if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])
    //    {
    //        NSData *data = characteristic.value;
    //        NSLog(@"%@",data);
    //    }
}
//13、更新描述值的时候会调用
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
{
    NSLog(@"新描述值==%@",descriptor.description);
}
//15、通知状态改变时调用
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if(error){
        NSLog(@"改变通知状态");
    }
}


#pragma mark - CBCentralManagerDelegate
// 返回蓝牙状态
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    NSString *status = @"";
    BOOL bluetooth_isOpen = NO;
    switch (central.state) {
        case CBManagerStateUnknown:
        {
            status = @"蓝牙状态未知";
            bluetooth_isOpen = NO;
        }
            break;
        case CBManagerStateResetting:
        {
            status = @"蓝牙状态重置中";
            bluetooth_isOpen = NO;
        }
            break;
        case CBManagerStateUnsupported:
        {
            status = @"蓝牙状态不支持";
            bluetooth_isOpen = NO;
        }
            break;
        case CBManagerStateUnauthorized:
        {
            status = @"蓝牙状态未授权";
            bluetooth_isOpen = NO;
        }
            break;
        case CBManagerStatePoweredOff:
        {
            status = @"蓝牙状态关闭";
            bluetooth_isOpen = NO;
        }
            break;
        case CBManagerStatePoweredOn:
        {
            status = @"蓝牙状态开启可用";
            bluetooth_isOpen = YES;
        }
            break;
        default:
            break;
    }
    self.bluetooth_isOpen = bluetooth_isOpen;
    self.blueStatusCallBack(bluetooth_isOpen,status);
}
/**
 扫描到设备
 
 @param central 中心管理者
 @param peripheral 扫描到的设备
 @param advertisementData 广告信息
 @param RSSI 信号强度
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
    if (![self.peripherals containsObject:peripheral])
    {
        [self.peripherals addObject:peripheral];
        NSLog(@"%@",peripheral);
        self.blueScanCallBack(peripheral.name);
    }
}
/**
 连接失败
 
 @param central 中心管理者
 @param peripheral 连接失败的设备
 @param error 错误信息
 */
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"连接失败");
    //    if ([peripheral.name isEqualToString:kBlePeripheralName])
    //    {
    //        [self.centralManager connectPeripheral:peripheral options:nil];
    //    }
}
/**
 连接断开
 
 @param central 中心管理者
 @param peripheral 连接断开的设备
 @param error 错误信息
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"断开连接");
    //    if ([peripheral.name isEqualToString:kBlePeripheralName])
    //    {
    //        [self.centralManager connectPeripheral:peripheral options:nil];
    //    }
}

/**
 连接成功
 
 @param central 中心管理者
 @param peripheral 连接成功的设备
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"连接设备:%@成功",peripheral.name);
    // 设置设备的代理
    peripheral.delegate = self;
    // services:传入nil代表扫描所有服务
    [peripheral discoverServices:nil];
}


#pragma mark - 初始化
/**
  初始化
 */
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.bluetooth_isOpen = NO;
    }
    return self;
}



#pragma mark - 单例初始化
/**
 * 单例初始化
 */
+ (instancetype)Manager
{
    static RocBluetoothManager *_RocManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _RocManager = [[super allocWithZone:nil] init];
    });
    return _RocManager;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    return [RocBluetoothManager Manager];
}
-(id)copyWithZone:(NSZone *)zone{
    return [RocBluetoothManager Manager];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return [RocBluetoothManager Manager];
}

@end
